In this notebook we work with cables. First we create code that takes as input a braid word of a knot K and outputs a braid words of its (p,q)-cable. We also present code that creates out of this alphabetical braid words, which can be used for example to put these cables into KnotJob.
In a second step, we use this code to obstruct certain cables from being positive or braid positive.
import string
import snappy
def torus_knot(p,q):
'''Returns a braid word of a positive torus knot.'''
return q*list(range(1,p))
def braid_index(word):
'''Returns the rbaid index of a word'''
return max([abs(x) for x in word])+1
def writhe(word):
'''Returns the writhe of a braid word.'''
wr=0
for w in word:
wr=wr+sign(w)
return wr
def cable(word,p,q):
'''Returns a braid word of the cable. (For positive p and arbitrary q.)'''
cable_word=[]
for i in word:
subword=[]
for t in range(0,p):
subword=subword+list(range(p*abs(i)+t,p*(abs(i)-1)+t,-1))
if i<0:
subword=[-j for j in subword]
cable_word=cable_word+subword
wr=writhe(word)
if (q-p*wr)<0:
cable_word=cable_word+(p*wr-q)*list(range(-1,-(p-1)-1,-1))
if (q-p*wr)>=0:
cable_word=cable_word+(-p*wr+q)*list(range(1,(p-1)+1,+1))
return cable_word
def braid_word_to_letters(word):
'''Returns an alphabetical describtion of the braid word.'''
upper=list(string.ascii_uppercase)
lower=list(string.ascii_lowercase)
stringword=''
for x in word:
for letter in lower:
if x==ord(letter) - 96:
stringword=stringword+letter
break
for letter in upper:
if -x==ord(letter) - 64:
stringword=stringword+letter
break
return stringword
For example we get braid words of T(2,2g+1)(2,0) and T(2,2g+1)(2,1), which we can then load in Mathematica or KnotJob to verify that its first Khovanov homology is non-vanishing.
for g in range(1,11):
print('T(2,2*',g,'+1)_(2,0)')
print(cable(torus_knot(2,2*g+1),2,0))
print(braid_word_to_letters(cable(torus_knot(2,2*g+1),2,0)))
print('T(2,2*',g,'+1)_(2,1)')
print(cable(torus_knot(2,2*g+1),2,1))
print(braid_word_to_letters(cable(torus_knot(2,2*g+1),2,1)))
Next, we show that in many examples (conjecturally all) that we study in the papers the cables are not braid positive whenever q < p w(K). We use again Ito's obstruction.
var('a,b,v,z')
R = PolynomialRing(ZZ, ['a','b'])
def HOMFLY(word):
'''
Computes the HOMFLY polynomial.
'''
K=snappy.Link(braid_closure=word)
K.simplify(mode='global')
L=K.sage_link()
h(v,z) = L.homfly_polynomial('v', 'z', 'az')
return h(v,z)
def normalized_HOMFLY(word):
'''
Given the braid word of an fibered knot. Returns Ito's normalized version of the HOMFLY.
'''
L=snappy.Link(braid_closure=word)
alex=L.exterior().alexander_polynomial()
g=alex.degree()/2
h(v,z)=HOMFLY(word)
homfly=(h((-a)^(-1/2),b^(1/2))*(-a)^(-g)).expand()
return homfly
def is_positive(poly):
'''Returns if the polynomial is positive.'''
m=matrix(R(poly).dict())
for x in m:
for y in x:
if y<0:
return False
return True
def gcd(p,q):
# Create the gcd of two positive integers.
while q != 0:
p, q = q, p%q
return p
def is_coprime(x, y):
return gcd(x, y) == 1
for r in range(2,5):
for s in range(3,7):
if is_coprime(r,s):
word=torus_knot(r,s)
for p in range(2,3):
for q in range(0,p*writhe(word)):
if is_coprime(p,q):
cable_word=cable(word,p,q)
if is_positive(normalized_HOMFLY(cable_word)):
print('T(',r,',',s,')_(',p,',',q,') has positive HOMFLYPT polynomial.')
else:
print('T(',r,',',s,')_(',p,',',q,') has NON-positive HOMFLYPT polynomial and thus is NOT braid positive.')
For 3-cables the obstruction seems to not work. However, for 4-cables it works well again:
for r in range(2,4):
for s in range(3,4):
if is_coprime(r,s):
word=torus_knot(r,s)
for p in range(3,4):
for q in range(0,p*writhe(word)):
if is_coprime(p,q):
cable_word=cable(word,p,q)
if is_positive(normalized_HOMFLY(cable_word)):
print('T(',r,',',s,')_(',p,',',q,') has positive HOMFLYPT polynomial.')
else:
print('T(',r,',',s,')_(',p,',',q,') has NON-positive HOMFLYPT polynomial and thus is NOT braid positive.')
for r in range(2,4):
for s in range(3,4):
if is_coprime(r,s):
word=torus_knot(r,s)
for p in range(4,5):
for q in range(0,12):
if is_coprime(p,q):
cable_word=cable(word,p,q)
if is_positive(normalized_HOMFLY(cable_word)):
print('T(',r,',',s,')_(',p,',',q,') has positive HOMFLYPT polynomial.')
else:
print('T(',r,',',s,')_(',p,',',q,') has NON-positive HOMFLYPT polynomial and thus is NOT braid positive.')
Next, we work with an iterated cable of the trefoil: First we take the (2,3)-cable of T(2,3) and compute its genus.
cable(torus_knot(2,3),2,3)
snappy.Link(braid_closure=cable(torus_knot(2,3),2,3)).knot_floer_homology()
Thus the (2,11)-cable of the (2,3)-cable of T(2,3) is again an L-space knot. We verify that:
print(cable(cable(torus_knot(2,3),2,3),2,11))
D=snappy.Link(braid_closure=cable(cable(torus_knot(2,3),2,3),2,11))
D
D.sage_link().plot()
D.knot_floer_homology()
It is not braid positive as we can see from Ito's obstruction:
normalized_HOMFLY(cable(cable(torus_knot(2,3),2,3),2,11))
However, we do not know if it is positive. The obstruction for positivity coming from the knot polynomials are all fulfilled.
D.jones_polynomial()
hom=HOMFLY(cable(cable(torus_knot(2,3),2,3),2,11))
hom.expand()
hom(1,z) #conway
def Cromwell_Morton_obstruction(homfly):
'''
Takes the homfly of a knot and checks the Cromwell-Morton obstruction of beeing valid.
'''
f=homfly(0.9,z)
coef=f.coefficients()
sign=coef[0].sign()
for c in coef:
if c.sign()!=sign:
#check the negative knot
f=homfly(1.1,z)
coef=f.coefficients()
sign=coef[0].sign()
for c in coef:
if c.sign()!=sign:
return False
return True
hom(1.1,z)